package server

import (
	"bytes"
	"context"
	"log"
	"minio-demo/client"
	"os"
	"path/filepath"
	"strconv"

	"github.com/gin-gonic/gin"
)

var engine *gin.Engine

func init() {
	engine = newEngine()
}

func newEngine() *gin.Engine {
	engine := gin.Default()
	engine.LoadHTMLGlob("templates/**")
	engine.GET("/", func(ctx *gin.Context) {
		ctx.HTML(200, "index.html", nil)
	})

	apiGroup := engine.Group("api")
	{
		apiGroup.POST("upload", func(ctx *gin.Context) {
			_, h, err := ctx.Request.FormFile("file")
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    500,
					"message": err.Error(),
				})
				return
			}

			isEnd := ctx.Request.Form.Get("isEnd")

			index, _ := strconv.Atoi(ctx.Request.Form.Get("index"))
			log.Printf("index: %d, isEnd: %s\n", index, isEnd)
			blockName := ctx.Request.Form.Get("blockName")

			ctx.SaveUploadedFile(h, "./upload/"+blockName)

			if isEnd == "true" {
				name_without_ext := ctx.Request.Form.Get("name_without_ext")
				log.Printf("name_without_ext: %s\n", name_without_ext)
				time := ctx.Request.Form.Get("time")
				bf := bytes.Buffer{}

				log.Printf("time: %s\n", time)
				names := []string{}
				for i := 1; i <= index; i++ {
					fn := time + "-" + name_without_ext + "-" + strconv.Itoa(i)
					b, _ := os.ReadFile("./upload/" + fn)
					w, _ := bf.Write(b)
					log.Printf("write data: %d\n", w)
					names = append(names, fn)

					log.Printf("append names: %s\n", fn)
				}

				datas := bf.Bytes()
				fn := ctx.Request.Form.Get("name")
				os.WriteFile("./upload/"+fn, datas, 0777)

				log.Printf("bytes length: %d\n", len(datas))

				for _, name := range names {
					os.Remove("./upload/" + name)
				}

			}

			ctx.JSON(200, gin.H{
				"code":    200,
				"message": "SUCCESS",
			})
		})

		apiGroup.POST("upload-to-minio", func(ctx *gin.Context) {
			f, h, err := ctx.Request.FormFile("file")
			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    500,
					"message": err.Error(),
				})
				return
			}

			fn := filepath.Base(h.Filename)

			fe := client.NewFromReader(fn, f)

			url, err := client.UploadReturnUrl(context.Background(), "test", fe)

			if err != nil {
				ctx.JSON(200, gin.H{
					"code":    500,
					"message": err.Error(),
				})
				return
			}

			ctx.JSON(200, gin.H{
				"code": 200,
				"url":  url,
			})
		})
	}

	return engine
}

func Run(addr string) {
	engine.Run(addr)
}
